package com.vcc.service.impl;


import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.vcc.core.util.RedisCustomizeUtils;
import com.vcc.data.entity.Permission;
import com.vcc.data.mapper.PermissionMapper;
import com.vcc.service.service.PermissionService;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.vcc.data.entity.table.BossRolePermissionTableDef.BOSS_ROLE_PERMISSION;
import static com.vcc.data.entity.table.PermissionTableDef.PERMISSION;

@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {


    @Override
    public List<Permission> listAll() {
        return super.list();
    }

    @Override
    public List<Permission> list() {
        String key = "all_permissions";
        if (RedisCustomizeUtils.hasKey(key)) {
            return RedisCustomizeUtils.getList(key, Permission.class);
        } else {
            List<Permission> list = super.list();
            RedisCustomizeUtils.set(key, list, 5L, TimeUnit.MINUTES);
            return list;
        }
    }

    @Override
    public boolean existsByCode(String code) {
        return queryChain().eq(Permission::getCode, code).exists();
    }

    @Override
    public List<Permission> listByHasPersonal(Boolean hasPersonal) {
//        return list(query().where(PERMISSION.HAS_PERSONAL.eq(hasPersonal)));
        return list();
    }

    @Override
    public List<Permission> listByRoleId(Long roleId) {
        return list(query()
                .select(PERMISSION.ALL_COLUMNS)
                .innerJoin(BOSS_ROLE_PERMISSION).on(BOSS_ROLE_PERMISSION.PERMISSION_ID.eq(PERMISSION.ID))
                .where(BOSS_ROLE_PERMISSION.BOSS_ROLE_ID.eq(roleId)));
    }

    @Override
    public List<Long> listIdParentId(Long parentId) {
        return listAs(query().select(PERMISSION.ID)
                .where(PERMISSION.PARENT_ID.eq(parentId).or(PERMISSION.ID.eq(parentId))), Long.class);
    }

    @Override
    public Boolean removeByRoleId(Long roleId) {
        return null;
    }

    @Override
    public Boolean updateHasPersonalById(Long id, Boolean hasPersonal) {
        boolean update = updateChain()
                .set(Permission::getHasPersonal, hasPersonal)
                .eq(Permission::getId, id)
                .update();
        if (update) {
            RedisCustomizeUtils.removeKey("all_permissions");
        }
        return update;
    }


    /**
     * 获取权限关联的所有ID
     *
     * @param permissionIds 前端传入的权限ID集合
     * @return 关联的所有权限ID集合
     */
    public Set<Long> getRelatedPermissionIds(Set<Long> permissionIds) {
        Set<Long> result = new HashSet<>();
        List<Permission> permissions = listAll();
        Map<Long, Permission> permissionMap = permissions.stream()
                .collect(Collectors.toMap(Permission::getId, Function.identity()));
        for (Long permissionId : permissionIds) {
            Permission permission = permissionMap.get(permissionId);
            if (permission == null) continue;

            if (isTopLevelPermission(permission)) {
                // 顶级权限：获取所有下级权限ID
                result.addAll(getAllDescendantIds(permissionId, permissionMap));
            } else {
                // 子权限：获取所有上级权限ID
                result.addAll(getAllAncestorIds(permissionId, permissionMap));
            }
            // 添加当前权限ID
            result.add(permissionId);
        }

        return result;
    }

    /**
     * 判断是否为顶级权限
     */
    private boolean isTopLevelPermission(Permission permission) {
        return permission.getParentId() == null || permission.getParentId() == 0;
    }

    /**
     * 获取指定权限的所有下级权限ID（递归）
     */
    private Set<Long> getAllDescendantIds(Long permissionId, Map<Long, Permission> permissionMap) {
        Set<Long> descendantIds = new HashSet<>();
        getDescendantIdsRecursive(permissionId, descendantIds, permissionMap);
        return descendantIds;
    }

    private void getDescendantIdsRecursive(Long parentId, Set<Long> descendantIds, Map<Long, Permission> permissionMap) {
        // 查找直接子权限
        List<Permission> children = permissionMap.values().stream()
                .filter(p -> parentId.equals(p.getParentId()))
                .toList();

        for (Permission child : children) {
            descendantIds.add(child.getId());
            // 递归获取下级
            getDescendantIdsRecursive(child.getId(), descendantIds, permissionMap);
        }
    }

    /**
     * 获取指定权限的所有上级权限ID
     */
    private Set<Long> getAllAncestorIds(Long permissionId, Map<Long, Permission> permissionMap) {
        Set<Long> ancestorIds = new HashSet<>();
        getAncestorIdsRecursive(permissionId, ancestorIds, permissionMap);
        return ancestorIds;
    }

    private void getAncestorIdsRecursive(Long currentId, Set<Long> ancestorIds, Map<Long, Permission> permissionMap) {
        Permission current = permissionMap.get(currentId);
        if (current == null || isTopLevelPermission(current)) {
            return;
        }

        Long parentId = current.getParentId();
        if (parentId != null && permissionMap.containsKey(parentId)) {
            ancestorIds.add(parentId);
            // 递归获取上级
            getAncestorIdsRecursive(parentId, ancestorIds, permissionMap);
        }
    }

    /**
     * 批量处理版本（优化性能）
     */
    public Set<Long> getRelatedPermissionIdsOptimized(Set<Long> permissionIds) {
        Set<Long> result = new HashSet<>();
        List<Permission> permissions = listAll();
        Map<Long, Permission> permissionMap = permissions.stream()
                .collect(Collectors.toMap(Permission::getId, Function.identity()));
        // 先找出所有顶级权限
        Set<Long> topLevelPermissions = permissionIds.stream()
                .map(permissionMap::get)
                .filter(Objects::nonNull)
                .filter(this::isTopLevelPermission)
                .map(Permission::getId)
                .collect(Collectors.toSet());

        // 找出所有非顶级权限
        Set<Long> nonTopPermissions = permissionIds.stream()
                .filter(id -> !topLevelPermissions.contains(id))
                .collect(Collectors.toSet());

        // 处理顶级权限：获取所有下级
        for (Long topId : topLevelPermissions) {
            result.addAll(getAllDescendantIds(topId, permissionMap));
            result.add(topId);
        }

        // 处理非顶级权限：获取所有上级
        for (Long nonTopId : nonTopPermissions) {
            result.addAll(getAllAncestorIds(nonTopId, permissionMap));
            result.add(nonTopId);
        }

        return result;
    }
}